import React, { useEffect, useRef, useState } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { NetworkData } from '../../hooks/useGeppettoWebSocket';
import { Box, Typography, Chip, Stack, Paper } from '@mui/material';

interface NetworkVisualizationProps {
  networkData: NetworkData | null;
}

interface SelectedNeuron {
  gid: number;
  cellType: string;
  pop: string;
  x: number;
  y: number;
  z: number;
}

export const NetworkVisualization: React.FC<NetworkVisualizationProps> = ({ networkData }) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const sceneRef = useRef<THREE.Scene | null>(null);
  const rendererRef = useRef<THREE.WebGLRenderer | null>(null);
  const cameraRef = useRef<THREE.PerspectiveCamera | null>(null);
  const controlsRef = useRef<OrbitControls | null>(null);
  const animationFrameRef = useRef<number | null>(null);
  const raycasterRef = useRef<THREE.Raycaster>(new THREE.Raycaster());
  const mouseRef = useRef<THREE.Vector2>(new THREE.Vector2());

  const [stats, setStats] = useState({
    neurons: 0,
    connections: 0,
    fps: 0,
  });

  const [selectedNeuron, setSelectedNeuron] = useState<SelectedNeuron | null>(null);
  const [hoveredNeuron, setHoveredNeuron] = useState<number | null>(null);

  // 初始化 Three.js 场景
  useEffect(() => {
    if (!containerRef.current) return;

    // 创建场景
    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0x1a1a1a);
    sceneRef.current = scene;

    // 创建相机
    const camera = new THREE.PerspectiveCamera(
      75,
      containerRef.current.clientWidth / containerRef.current.clientHeight,
      0.1,
      1000
    );
    camera.position.set(50, 50, 100);
    cameraRef.current = camera;

    // 创建渲染器
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(containerRef.current.clientWidth, containerRef.current.clientHeight);
    containerRef.current.appendChild(renderer.domElement);
    rendererRef.current = renderer;

    // 创建控制器
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;
    controls.screenSpacePanning = false;
    controls.minDistance = 10;
    controls.maxDistance = 500;
    controlsRef.current = controls;

    // 添加光源
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);
    
    const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
    directionalLight.position.set(10, 10, 10);
    scene.add(directionalLight);

    // 添加网格辅助线
    const gridHelper = new THREE.GridHelper(100, 10, 0x444444, 0x222222);
    scene.add(gridHelper);

    // 添加坐标轴
    const axesHelper = new THREE.AxesHelper(50);
    scene.add(axesHelper);

    // FPS 计算
    let lastTime = performance.now();
    let frames = 0;

    // 动画循环
    const animate = () => {
      animationFrameRef.current = requestAnimationFrame(animate);
      
      controls.update();
      renderer.render(scene, camera);

      // 计算 FPS
      frames++;
      const currentTime = performance.now();
      if (currentTime >= lastTime + 1000) {
        setStats(prev => ({ ...prev, fps: frames }));
        frames = 0;
        lastTime = currentTime;
      }
    };
    animate();

    // 窗口大小调整
    const handleResize = () => {
      if (!containerRef.current || !camera || !renderer) return;

      const width = containerRef.current.clientWidth;
      const height = containerRef.current.clientHeight;

      camera.aspect = width / height;
      camera.updateProjectionMatrix();
      renderer.setSize(width, height);
    };
    window.addEventListener('resize', handleResize);

    // 鼠标移动事件 - 高亮悬停的神经元
    const handleMouseMove = (event: MouseEvent) => {
      if (!containerRef.current || !camera || !scene) return;

      const rect = containerRef.current.getBoundingClientRect();
      mouseRef.current.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
      mouseRef.current.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

      raycasterRef.current.setFromCamera(mouseRef.current, camera);
      const intersects = raycasterRef.current.intersectObjects(
        scene.children.filter(obj => obj.userData.type === 'neuron')
      );

      if (intersects.length > 0) {
        const neuron = intersects[0].object;
        setHoveredNeuron(neuron.userData.gid);
        document.body.style.cursor = 'pointer';
      } else {
        setHoveredNeuron(null);
        document.body.style.cursor = 'default';
      }
    };

    // 鼠标点击事件 - 选择神经元
    const handleClick = (event: MouseEvent) => {
      if (!containerRef.current || !camera || !scene) return;

      const rect = containerRef.current.getBoundingClientRect();
      mouseRef.current.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
      mouseRef.current.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

      raycasterRef.current.setFromCamera(mouseRef.current, camera);
      const intersects = raycasterRef.current.intersectObjects(
        scene.children.filter(obj => obj.userData.type === 'neuron')
      );

      if (intersects.length > 0) {
        const neuron = intersects[0].object;
        const mesh = neuron as THREE.Mesh;
        setSelectedNeuron({
          gid: neuron.userData.gid,
          cellType: neuron.userData.cellType,
          pop: neuron.userData.pop,
          x: mesh.position.x,
          y: mesh.position.y,
          z: mesh.position.z,
        });
      } else {
        setSelectedNeuron(null);
      }
    };

    renderer.domElement.addEventListener('mousemove', handleMouseMove);
    renderer.domElement.addEventListener('click', handleClick);

    // 清理
    return () => {
      window.removeEventListener('resize', handleResize);

      if (renderer && renderer.domElement) {
        renderer.domElement.removeEventListener('mousemove', handleMouseMove);
        renderer.domElement.removeEventListener('click', handleClick);
      }

      if (animationFrameRef.current) {
        cancelAnimationFrame(animationFrameRef.current);
      }

      if (renderer) {
        renderer.dispose();
      }

      if (containerRef.current && renderer.domElement) {
        containerRef.current.removeChild(renderer.domElement);
      }

      document.body.style.cursor = 'default';
    };
  }, []);

  // 渲染网络数据
  useEffect(() => {
    if (!networkData || !sceneRef.current) return;

    const scene = sceneRef.current;

    // 清空场景中的网络对象
    const objectsToRemove: THREE.Object3D[] = [];
    scene.children.forEach(child => {
      if (child.userData.type === 'neuron' || child.userData.type === 'connection') {
        objectsToRemove.push(child);
      }
    });
    objectsToRemove.forEach(obj => {
      scene.remove(obj);
      if (obj instanceof THREE.Mesh || obj instanceof THREE.Line) {
        obj.geometry.dispose();
        if (Array.isArray(obj.material)) {
          obj.material.forEach(mat => mat.dispose());
        } else {
          obj.material.dispose();
        }
      }
    });

    // 渲染神经元节点
    const neuronGeometry = new THREE.SphereGeometry(1, 16, 16);
    
    networkData.cells.forEach(cell => {
      const material = new THREE.MeshPhongMaterial({
        color: cell.cellType === 'PYR' ? 0x00ff00 : 0xff0000,
        emissive: cell.cellType === 'PYR' ? 0x003300 : 0x330000,
        shininess: 30,
      });
      
      const sphere = new THREE.Mesh(neuronGeometry, material);
      sphere.position.set(cell.x, cell.y, cell.z);
      sphere.userData = { 
        type: 'neuron', 
        gid: cell.gid,
        cellType: cell.cellType,
        pop: cell.pop,
      };
      
      scene.add(sphere);
    });

    // 渲染连接
    const connectionMaterial = new THREE.LineBasicMaterial({ 
      color: 0x888888, 
      opacity: 0.3, 
      transparent: true 
    });

    networkData.connections.forEach(conn => {
      const preCell = networkData.cells.find(c => c.gid === conn.preGid);
      const postCell = networkData.cells.find(c => c.gid === conn.postGid);

      if (preCell && postCell) {
        const points = [
          new THREE.Vector3(preCell.x, preCell.y, preCell.z),
          new THREE.Vector3(postCell.x, postCell.y, postCell.z),
        ];
        const geometry = new THREE.BufferGeometry().setFromPoints(points);
        const line = new THREE.Line(geometry, connectionMaterial);
        line.userData = { 
          type: 'connection',
          preGid: conn.preGid,
          postGid: conn.postGid,
          weight: conn.weight,
        };
        scene.add(line);
      }
    });

    // 更新统计信息
    setStats(prev => ({
      ...prev,
      neurons: networkData.cells.length,
      connections: networkData.connections.length,
    }));

    // 调整相机位置以适应网络
    if (cameraRef.current && networkData.cells.length > 0) {
      const bounds = calculateBounds(networkData.cells);
      const center = new THREE.Vector3(
        (bounds.minX + bounds.maxX) / 2,
        (bounds.minY + bounds.maxY) / 2,
        (bounds.minZ + bounds.maxZ) / 2
      );
      
      const size = Math.max(
        bounds.maxX - bounds.minX,
        bounds.maxY - bounds.minY,
        bounds.maxZ - bounds.minZ
      );
      
      const distance = size * 2;
      cameraRef.current.position.set(
        center.x + distance,
        center.y + distance,
        center.z + distance
      );
      
      if (controlsRef.current) {
        controlsRef.current.target.copy(center);
        controlsRef.current.update();
      }
    }

    console.log(`✅ 3D 渲染完成: ${networkData.cells.length} 个神经元, ${networkData.connections.length} 个连接`);
  }, [networkData, selectedNeuron, hoveredNeuron]);

  // 计算网络边界
  const calculateBounds = (cells: any[]) => {
    let minX = Infinity, maxX = -Infinity;
    let minY = Infinity, maxY = -Infinity;
    let minZ = Infinity, maxZ = -Infinity;

    cells.forEach(cell => {
      minX = Math.min(minX, cell.x);
      maxX = Math.max(maxX, cell.x);
      minY = Math.min(minY, cell.y);
      maxY = Math.max(maxY, cell.y);
      minZ = Math.min(minZ, cell.z);
      maxZ = Math.max(maxZ, cell.z);
    });

    return { minX, maxX, minY, maxY, minZ, maxZ };
  };

  return (
    <Box>
      {/* 统计信息 */}
      <Stack direction="row" spacing={1} sx={{ mb: 2 }} flexWrap="wrap">
        <Chip
          label={`神经元: ${stats.neurons}`}
          color="success"
          size="small"
        />
        <Chip
          label={`连接: ${stats.connections}`}
          color="primary"
          size="small"
        />
        <Chip
          label={`FPS: ${stats.fps}`}
          color={stats.fps >= 30 ? 'success' : 'warning'}
          size="small"
        />
        {hoveredNeuron !== null && (
          <Chip
            label={`悬停: GID ${hoveredNeuron}`}
            color="info"
            size="small"
          />
        )}
      </Stack>

      {/* 选中神经元详情 */}
      {selectedNeuron && (
        <Paper sx={{ p: 2, mb: 2, bgcolor: '#f5f5f5' }}>
          <Typography variant="subtitle2" gutterBottom>
            选中神经元详情
          </Typography>
          <Stack direction="row" spacing={2} flexWrap="wrap">
            <Typography variant="body2">
              <strong>GID:</strong> {selectedNeuron.gid}
            </Typography>
            <Typography variant="body2">
              <strong>类型:</strong> {selectedNeuron.cellType}
            </Typography>
            <Typography variant="body2">
              <strong>种群:</strong> {selectedNeuron.pop}
            </Typography>
            <Typography variant="body2">
              <strong>位置:</strong> ({selectedNeuron.x.toFixed(2)}, {selectedNeuron.y.toFixed(2)}, {selectedNeuron.z.toFixed(2)})
            </Typography>
          </Stack>
        </Paper>
      )}

      {/* 3D Canvas */}
      <div
        ref={containerRef}
        style={{
          width: '100%',
          height: '600px',
          border: '1px solid #ccc',
          borderRadius: '4px',
          backgroundColor: '#1a1a1a',
        }}
      />

      {/* 提示信息 */}
      <Typography variant="caption" color="text.secondary" sx={{ mt: 1, display: 'block' }}>
        💡 提示: 使用鼠标左键旋转，滚轮缩放，右键平移。点击神经元查看详情。
      </Typography>
    </Box>
  );
};

